#ifndef LOGGER_H
#define LOGGER_H

#include <iostream>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"

#define LOG_TITLE "test_log"
#define LOG_PATH "./log/tmp.log"
#define MAX_FILES 3
#define MAX_SIZE (1024 * 1024 * 2)
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)

namespace simple_logger {
    class Logger {
    private:
        std::shared_ptr<spdlog::logger> console_logger;

        Logger() {
            try {
                this->console_logger = spdlog::rotating_logger_mt(LOG_TITLE, LOG_PATH, MAX_SIZE, MAX_FILES);
                spdlog::set_level(spdlog::level::debug);
                spdlog::set_pattern("[%n] [%Y-%m-%d %H:%M:%S.%e] [%l] %v");
                spdlog::set_default_logger(this->console_logger);
            }
            catch (const spdlog::spdlog_ex &ex) {
                std::cout << "Log failed: " << ex.what() << std::endl;
                exit(-1);
            }
        }

        Logger(Logger const &) = delete;
        void operator=(Logger const &) = delete;

    public:
        ~Logger() {
            //std::cout << "Called destructor of Logger" << std::endl;
        }

        static Logger &get_logger() {
            static Logger new_loger;
            return new_loger;
        }

        void log(std::string a_str) {
            this->console_logger->debug("{}", a_str);
        }

        template<typename... Args>
        void debug(const char *fmt, const Args... args) {
            this->console_logger->debug(fmt, args...);
        }

        template<typename... Args>
        void info(const char *fmt, const Args... args) {
            this->console_logger->info(fmt, args...);
        }

        template<typename... Args>
        void warn(const char *fmt, const Args... args) {
            this->console_logger->warn(fmt, args...);
        }

        template<typename... Args>
        void critical(const char *fmt, const Args... args) {
            this->console_logger->critical(fmt, args...);
        }
    };
}

simple_logger::Logger& my_logger = simple_logger::Logger::get_logger();
extern simple_logger::Logger& my_logger;

#endif //LOGGER_H
